import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.utils.Timer;

import haxe.FastList;
import haxe.Timer;

import nme.Assets;
import TileModel;
import HealthBarView;
import BaseLevel;
import Kongregate;

import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;

class SquareCollisionLevel extends BaseLevel
{
  
  private var _pinkMap:Array<Array<Int>>;  
  private static inline var MAX_TILE_SIZE:Int = 64;
  private static inline var MAP_COLUMNS:Int = 19;
  private static inline var MAP_ROWS:Int = 8;
  
  //tile ID s in tile sheet
  private static inline var BOX:Int = 00;
  private static inline var SKY:Int = 10;
  private static inline var PLATFORM:Int = 11;
  private static inline var MACHINE_GUN:Int = 01;
  private static inline var PISTOL:Int = 02;
  private static inline var SHOTGUN:Int = 03;
  private static inline var DOOR:Int = 13;

  private static inline var PINK:Int = 21;
  private static inline var BLUE:Int = 20;

  private static inline var PinkRadius:Float = 20.5;
  private static inline var BlueRadius:Float = 20.5;
  public var _SquareModel:SquareModel;
  public var _SquareView:PlayerSquareView;
  public var _SquareController:SquareController;
  public var _s1:SquareModel;
  public var _s1_View:SquareView;
  public var _s2:SquareModel;
  public var _s2_View:SquareView;
  public var _s3:SquareModel;
  public var _s3_View:SquareView;
  public var _s4:SquareModel;
  public var _s4_View:SquareView;
  public var _s5:SquareModel;
  public var _s5_View:SquareView;
  public var _VectorModel:VectorModel;
  public var _VectorView:VectorView;
  private var _SpriteLayer:Sprite;
  public var  WelcomeText:TextField;
  public var  SquareExplationText:TextField;
  public var  SquareForumlaText:TextField;
  public var  SquareSizeText:TextField;

  public function new(stage:Dynamic){
  super(stage);
  MAP_COLUMNS = 26;
    removeChild(_staticBackgroundBitmap);
    removeChild(_backgroundBitmap);
    removeChild(_foregroundBitmap);
  _staticBackgroundBitmapData = Assets.getBitmapData("Cardboard_Background.png");
  _staticBackgroundBitmap = new Bitmap(_staticBackgroundBitmapData);

  _backgroundBitmapData = new BitmapData(MAP_COLUMNS * MAX_TILE_SIZE, 
          MAP_ROWS * MAX_TILE_SIZE, true, 0);
  _backgroundBitmap = new Bitmap(_backgroundBitmapData);

  _foregroundBitmapData = new BitmapData(MAP_COLUMNS * MAX_TILE_SIZE, 
          MAP_ROWS * MAX_TILE_SIZE, true, 0);
  _foregroundBitmap = new Bitmap(_foregroundBitmapData);

  _SpriteLayer = new Sprite();
  _SpriteLayer.graphics.beginFill(0x0000000,0);
  _SpriteLayer.graphics.drawRect(0,0,MAP_COLUMNS * MAX_TILE_SIZE,MAP_ROWS * MAX_TILE_SIZE);
  _SpriteLayer.visible = true;

  _camera = new Rectangle (0, 0, stage.stageWidth, stage.stageHeight);

    addChild(_staticBackgroundBitmap);
    addChild(_backgroundBitmap);
    addChild(_foregroundBitmap);
    addChild(_SpriteLayer);
  _platformMap = 
	[
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,SKY,PLATFORM],
		  [PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM,PLATFORM]
	];
  _gameObjectMap = 
	[
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,DOOR,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,DOOR,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	    [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
	  ]  ;


  buildReserveEnemies();


  // myTimer = new Timer(12);
  //   myTimer.addEventListener("timer", OnEnter);
  //   myTimer.start();
  //Add the game bitmaps
			  
			  //Run the buildMap method to convert the
			  //map array data into a visual display
			  

      
    SquareExplationText = new TextField();
    SquareExplationText.htmlText = "<font size ='16'>In order to calculate if a two square have collied. need to Calculate the distance between the two centers. Then determine the vertical and horizontal distance between to two squares.

If the Vertical distance is half of the combined height of the squares and the horizontal distance is less than half of the combined width then the squares have collided.</font>";
    SquareExplationText.x = 150;SquareExplationText.y = 5;
    SquareExplationText.width = 250; SquareExplationText.height = 270;
    SquareExplationText.wordWrap = true;
    SquareExplationText.border = true;
    _SpriteLayer.addChild(SquareExplationText);

    SquareForumlaText = new TextField();
    SquareForumlaText.width = 450; SquareForumlaText.height = 260;
    SquareForumlaText.htmlText = "<font size ='16'>//_s1 is square one and _s2 is square two.
//Make sure to use center of the square for xPos and yPos
      line = new Vector(_s1.centerX , _s1.centerY , _s2.centerX  , _s2.centerY ); 
      if(Math.abs(line.vx) &lt; _s1.width * 0.5 + _s2.width * 0.5)
      {
        if(Math.abs(line.vy) &lt; _s1.height * 0.5 + _s2.height * 0.5)
        {    
        //Collided
        }
      }</font>";
    SquareForumlaText.x = 500;SquareForumlaText.y = 50;

    SquareForumlaText.wordWrap = true;
    SquareForumlaText.border = true;
    _SpriteLayer.addChild(SquareForumlaText);


    SquareSizeText = new TextField();
    SquareSizeText.width = 150; SquareSizeText.height = 180;
    SquareSizeText.htmlText = "<font size ='16'>This equation can be extended to squares of different sizes, including differently shaped rectangles.</font>";
    SquareSizeText.x = 1200;SquareSizeText.y = 50;

    SquareSizeText.wordWrap = true;
    SquareSizeText.border = true;
    _SpriteLayer.addChild(SquareSizeText);
    }
public override function Load(inVolume:Bool,inSound:Bool,inKongVar:CKongregate,inDifficulty:Int)
{
 super.Load(inVolume,inSound,inKongVar,inDifficulty);
 buildMap(_platformMap);
 buildMap(_gameObjectMap);
 _SquareModel = new SquareModel();
_SquareModel.width = 50;_SquareModel.height = 50;
_SquareModel.setX = 64*3.5;_SquareModel.setY = 384;
  _SquareController = new SquareController(_SquareModel);
 _SquareView = new PlayerSquareView(_SquareModel,_SquareController,stage);

  _SpriteLayer.addChild(_SquareView);

  _s1 = new SquareModel();
  _s1_View = new SquareView(_s1);
  _s1.xPos = 576;_s1.yPos = 384;
  _s1.width = 60;_s1.height = 60;
  _SpriteLayer.addChild(_s1_View);

  
  _VectorModel = new VectorModel(_SquareModel.xPos+_SquareModel.width/2,_SquareModel.yPos+_SquareModel.height/2, _s1.xPos+_s1.width/2,_s1.yPos+_s1.width/2);
  _VectorView = new VectorView(_VectorModel,new Rectangle(0,0,0,0),1);
  _SpriteLayer.addChild(_VectorView);

  _s2 = new SquareModel();
  _s2.width = 10;_s2.height = 20;
  _s2.setX = 1280;_s2.setY = 384;
  _s2_View = new SquareView(_s2);
  _SpriteLayer.addChild(_s2_View);

  _s3 = new SquareModel();
  _s3.width = 10;_s3.height = 10;
  _s3.setX = 1380;_s3.setY = 320;
  _s3_View = new SquareView(_s3);
  _SpriteLayer.addChild(_s3_View);
  

  _s4 = new SquareModel();
  _s4.width = 60;_s4.height = 60;
  _s4.setX = 1234;_s4.setY = 237;
  _s4_View = new SquareView(_s4);
  _SpriteLayer.addChild(_s4_View);

  _s5 = new SquareModel();
  _s5.width = 5;_s5.height = 5;
  _s5.setX = 1485;_s5.setY = 200;
  _s5_View = new SquareView(_s5);
  _SpriteLayer.addChild(_s5_View);
  
}

public override function checkWin():Bool
{
  if(!_SquareModel.exit)
    {return false;}
  var Door1 = new SquareModel();
  Door1.xPos = 1*64;
  Door1.yPos = 6*64;
  Door1.width = 64;
  Door1.height = 64;
  var boxSquare = new SquareModel();
  boxSquare.xPos = _SquareModel.xPos;
  boxSquare.yPos = _SquareModel.yPos;
  boxSquare.width = _SquareModel.width;
  boxSquare.height = _SquareModel.height;
  if(_collisionController.squareModelCollision(Door1,boxSquare))
  {
    return true;
  }
    var Door2 = new SquareModel();
  Door2.xPos = 23*64;
  Door2.yPos = 6*64;
  Door2.width = 64;
  Door2.height = 64;
  if(_collisionController.squareModelCollision(Door2,boxSquare))
  {
    return true;
  }
  return  false;
}

  public  override function UnLoad()
  {
   _SpriteLayer.removeChild(_SquareView);
   _SpriteLayer.removeChild(_s1_View);
   if(_SpriteLayer.contains(_VectorView))
   {
    _SpriteLayer.removeChild(_VectorView);
   }

      super.UnLoad();
      //_MainCharacterController = null;

  }
public function checkCollisionSquare(_s1:SquareModel,_s2:SquareModel,view:SquareView)
{
	if(_collisionController.squareModelCollision(_s1,_s2))
	{
	  view.hit();
	}
	else
	{
	  view.unHit();
	}
}
override function OnEnter(e:flash.events.Event)
{
    try
    {
      if(checkWin())
      {	
	_SquareModel.exit = false;
	UnLoad();
	this.removeEventListener(Event.ENTER_FRAME, OnEnter);
	dispatchEvent(new Event("LevelFinished"));return;
      }
      _SquareModel.exit = false;
      if(Pause == "Paused")
      {
	return;
      }	

      _VectorModel.update(0,0,0,0);
      if(_SquareModel.xPos > 1088)
      {

	checkCollisionSquare(_SquareModel, _s2,_s2_View);
	//_s3 and _s4 have no radius.
	checkCollisionSquare(_SquareModel, _s3,_s3_View);
	checkCollisionSquare(_SquareModel, _s4,_s4_View);

	checkCollisionSquare(_SquareModel, _s5,_s5_View);
      }
      else
      {  
	_VectorModel.update(_SquareModel.xPos+_SquareModel.width/2,_SquareModel.yPos+_SquareModel.height/2, _s1.xPos+_s1.width/2,_s1.yPos+_s1.width/2);
	checkCollisionSquare(_SquareModel, _s1,_s1_View);
      }
	
      _SquareModel.update();      
      //Clear the stage bitmap from the previous frame so that it's
      //blank when you add the new tile positions
      _foregroundBitmapData.fillRect(_foregroundBitmapData.rect, 0);
      //Set up the camera to focus on the cat
      _camera.x = _SquareModel.xPos-Constants.flashWidth*0.5;
      _camera.y = 0;
      
      //Check the camera's game world boundaries
      //Left
      if(_camera.x < 0)
      {
	_camera.x = 0;
      }
      
      //Right
      if(_camera.x > (MAP_COLUMNS * MAX_TILE_SIZE) 
	- Constants.flashWidth)
      {
	_camera.x = (MAP_COLUMNS * MAX_TILE_SIZE) - Constants.flashWidth;
      }
      
      //Bottom
      if(_camera.y > (MAP_ROWS * MAX_TILE_SIZE) - Constants.flashHeight)
      {
	_camera.y = (MAP_ROWS * MAX_TILE_SIZE) - Constants.flashHeight;
      }
      
      //Top
      if(_camera.y < 0)
      {
	_camera.y = 0;
      }
    
      //Update the box's Model

      //if Shoting
//       shotVector.update(0, 0,0,0);
//       	var y2 =  _SquareModel.yPos + _SquareModel.height/2;
// 	var y1 = mouseY;
// 	
// 	var x2 = _SquareModel.xPos +_SquareModel.width/2;
// 	var x1 = mouseX+_camera.x;
// 	var m = (y2 - y1 )/(x2 - x1);
// 	var b = (y2) - m*(x2);
// 	var testVector = new VectorModel();
// 	testVector.update(x2, y2,x1,y1);

    _collisionMap = [[]];
    for(row in 0...MAP_ROWS)
    {
      _collisionMap[row] = [];
      for(column in 0...MAP_ROWS)	
      {
	_collisionMap[row][column] = new List<TileModel>();
      }
    }
    for(enemy in _enemies)
    {
	_collisionMap[enemy.model.mapRow][enemy.model.mapColumn].add(enemy.model);
	enemy.model.update();
      if (enemy.model.xPos + (enemy.model.width) > maxX)
      {
	enemy.model.setX = maxX - (enemy.model.width);
	enemy.model.vx = 0;
      }
      else if (enemy.model.xPos < minX)
      {
	      enemy.model.setX = minX;
	      enemy.model.vx = 0;
      }
      if (enemy.model.yPos < 0)
      {
	      enemy.model.setY = 0;
	      enemy.model.vy = 0;
      }

      else if (enemy.model.yPos + enemy.model.height > Constants.flashHeight && enemy.model.vy > 0)
      {
	      enemy.model.setY = Constants.flashHeight - enemy.model.height;
	      enemy.model.vy = 0;
      } 
	drawGameObject(enemy.model,_foregroundBitmapData);
    }
// 	for(column in -1...2)
// 	{
// 	  for(row in -1...2)
// 	  {
// 	    if(_SquareModel.mapRow + row < _collisionMap.length &&
// 	       _SquareModel.mapRow + row >= 0 &&
// 	       _SquareModel.mapColumn + column < _collisionMap[0].length &&
// 	       _SquareModel.mapColumn + column >= 0)
// 	    {		
// 	      	for(model in _collisionMap[_SquareModel.mapRow + row ][_SquareModel.mapColumn + column])
// 		{
// 		  //collision
// 		}
// 	    }
// 	  }
// 	}
      //Stop the box at the stage boundaries
      //StageBoundaries.stopBitmap(_SquareModel, stage);
      maxX = MAP_COLUMNS * MAX_TILE_SIZE;
      if (_SquareModel.xPos + _SquareModel.width > maxX)
      {
	_SquareModel.setX = maxX - (_SquareModel.width);
	_SquareModel.vx = 0;
      }
      else if (_SquareModel.xPos < minX)
      {
	      _SquareModel.setX = minX;
	      _SquareModel.vx = 0;
      }
      if (_SquareModel.yPos  < 0)
      {
	      _SquareModel.setY =  0;
	      _SquareModel.vy = 0;
      }
      else if (_SquareModel.yPos + _SquareModel.height > Constants.flashHeight && _SquareModel.vy > 0)
      {
	      _SquareModel.setY = Constants.flashHeight - _SquareModel.height;
	      _SquareModel.vy = 0;
      } 
      
 
      //Check for collisions with the platforms
//       _collisionController.platformCollision
// 	(_SquareModel, _platformMap, MAX_TILE_SIZE, PLATFORM);

      //Blit the box on the foreground bitmap
    _collisionController.platformCollisionSquareModel(_SquareModel,_platformMap,MAX_TILE_SIZE,PLATFORM);
      //Scroll the game world
      _foregroundBitmap.scrollRect = _camera;
      _backgroundBitmap.scrollRect = _camera;
      _SpriteLayer.scrollRect = _camera;

      //_gunView.scrollRect = _camera;
      //drawGunObject(_gunModel,_currentGunBitmapData, _foregroundBitmapData); 
    }
catch(err:Dynamic)
    {
    trace(err.message);
    }
}

  public override function buildReserveEnemies()
  {
  }
}